package com.fengwk.resource.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fengwk.resource.dao.ResFileDao;
import com.fengwk.resource.dao.ResServerDao;
import com.fengwk.resource.face.constant.ResourceConstant;
import com.fengwk.resource.face.entity.ResFile;
import com.fengwk.resource.face.entity.ResServer;
import com.fengwk.resource.face.model.File;
import com.fengwk.resource.service.FileService;
import com.fengwk.support.exception.BaseException;
import com.fengwk.support.util.BeanUtils;
import com.fengwk.support.util.CollectionUtils;
import com.fengwk.support.util.FileExtensionUtils;
import com.fengwk.support.util.StringUtils;
import com.fengwk.support.util.WebUtils;

@Service
public class FileServiceImpl implements FileService {
	
	@Autowired
	private ResFileDao rfDao;
	@Autowired
	private ResServerDao rsDao;
	
	@Transactional
	@Override
	public ResFile save(Long fileId, String name, String type, String size, Long length,
			String relativePath, String absolutePath, Long userId, String md5, Long serverId, String linkUrl) {
		ResFile rf = new ResFile();
		rf.setFileId(fileId);
		rf.setName(name);
		rf.setType(type);
		rf.setSize(size);
		rf.setLength(length);
		rf.setRelativePath(relativePath);
		rf.setAbsolutePath(absolutePath);
		rf.setCreateTime(System.currentTimeMillis());
		rf.setUserId(userId);
		rf.setMd5(md5);
		rf.setServerId(serverId);
		rf.setLinkUrl(linkUrl);
		rfDao.insert(rf);
		return rf;
	}
	
	@Override
	public File getLastByMd5(String md5) {
		return toFile(rfDao.findLatestByMd5(md5));
	}
	
	@Override
	public File getByFileId(Long fileId) {
		return CollectionUtils.getFirstFromList(
				listByFileIds(CollectionUtils.buildList(fileId, true)));
	}
	
	@Override
	public List<File> listByFileIds(Collection<Long> fileIds) {
		List<ResFile> rfList = rfDao.queryInFileIds(fileIds);
		return toFileList(rfList);
	}
	
	@Override
	public List<File> toFileList(Collection<ResFile> rfs) {
		List<Long> serverIdList = CollectionUtils.toListWithTypeConvert(rfs, rf -> rf.getServerId());
		List<ResServer> rsList = rsDao.queryInServerIds(serverIdList);
		Map<Long, ResServer> sidRsMap = CollectionUtils.toMap(rsList, rs -> rs.getServerId());
		
		return CollectionUtils.toListWithTypeConvert(rfs, rf -> {
			// 构建
			File f = BeanUtils.convert(rf, File.class);
			
			Long serverId = f.getServerId();
			
			if (serverId == null) {
				// 使用linkUrl
				String linkUrl = f.getLinkUrl();
				f.setUrl(linkUrl);
				f.setRealUrl(linkUrl);
				return f;
			}
			
			/* 资源路径 */
			String url = ResourceConstant.PRE_RESOURCE_SERVER_URL 
					+ WebUtils.QUERY + "fileId=" + rf.getFileId();
			
			String thumbnailUrl = null;
			
			/* 真实路径 */
			// 默认前缀
			String urlPre = ResourceConstant.PRE_RESOURCE_SERVER_URL;
			// 优先使用服务器前缀
			ResServer rs = sidRsMap.get(serverId);
			if (rs != null)
				urlPre = rs.getFileUrlPrefix();
			
			// 真实路径拼接
			String relativePath = rf.getRelativePath();
			String realUrl = urlPre + fixRelativePath(relativePath);
			
			// 真实缩略图路径拼接
			String realThumbnailUrl = null;
			String[] urlSplits = FileExtensionUtils.split(realUrl);
			if(urlSplits != null && shouldThumbnail(urlSplits[1])) {
				thumbnailUrl = url + WebUtils.AND + "thumbnail=true";
				realThumbnailUrl = urlSplits[0] + ResourceConstant.THUMBNAIL_SUFFIX + FileExtensionUtils.EXTENTSION_CHARACTER + urlSplits[1];
			}
			
			f.setUrl(url);
			f.setThumbnailUrl(thumbnailUrl);
			f.setRealUrl(realUrl);
			f.setRealThumbnailUrl(realThumbnailUrl);
			return f;
		});
	}
	
	private File toFile(ResFile rf) {
		if (rf == null)
			return null;
		return CollectionUtils.getFirstFromList(toFileList(CollectionUtils.buildList(rf, true)));
	}
	
	private String fixRelativePath(String relativePath) {
		if (StringUtils.isNotBlank(relativePath) && relativePath.startsWith(ResourceConstant.PRE_FILE_RELATIVE_PATH)) 
			return relativePath.replaceFirst(ResourceConstant.PRE_FILE_RELATIVE_PATH, "");
			
		return relativePath;
	}
	
	@Override
	public File getDefaultIcon() {
		return toFile(rfDao.findByFileId(ResourceConstant.DEFAULT_ICON_ID));
	}

	@Override
	public String getRealUrl(Long fileId, Boolean thumbnail) {
		File f = getByFileId(fileId);
		if (f == null)
			throw new BaseException("文件" + fileId + "不存在");
		String url = null;
		if (thumbnail != null && thumbnail)
			url = f.getRealThumbnailUrl();
		if (url == null)
			url = f.getRealUrl();
		return url;
	}

    @Override
    public boolean shouldThumbnail(String type) {
        return type != null && FileExtensionUtils.matchExtension(type, FileExtensionUtils.IMAGE_SET) && !type.contains("gif");
    }
	
}
